﻿using System;
using KinonekoSoftware.CodariaDB.Documents.Shenanigans.Forum;

namespace KinonekoSoftware.Studio.Pages.Shenanigans
{
    public partial class ForumGalleryViewModel : TabViewModelSub
    {
        private const    int           PerPageCount = 8;
        private readonly ForumEngine   _engine;
        private readonly List<Discuss> _collection;

        private int    _version;
        private int    _pageCount;
        private int    _pageIndex;
        private Discuss _selected;


        public ForumGalleryViewModel()
        {
            _engine     = Platform.GetEngine<ForumEngine>();
            _collection = new List<Discuss>(32);
            Discusses   = new ObservableCollection<Discuss>();

            NextPageCommand      = CreateCommand(DoNextPageCommand);
            PreviousPageCommand  = CreateCommand(DoPreviousPageCommand);
            AddDiscussCommand    = CreateCommand(DoAddDiscussCommand);
            OpenDiscussCommand   = CreateCommand<Discuss>(DoOpenDiscussCommand);
            RemoveDiscussCommand = CreateCommand<Discuss>(DoRemoveDiscussCommand);
        }


        protected override void OnStart()
        {
            InvalidateDataSource();
            base.OnStart();
        }

        protected override void OnResume()
        {
            if (_version != _engine.Version)
            {
                InvalidateDataSource();
            }

            base.OnResume();
        }

        private void InvalidateDataSource()
        {
            //
            //
            _collection.AddMany(_engine.GetDiscusses(), true);

            //
            // 重新计算页面位置。
            InvalidatePageSource();

        }

        private void InvalidatePageSource()
        {
            //
            // 
            _pageCount = (_collection.Count + (PerPageCount - 1)) / PerPageCount;
            _pageIndex = 1;

            //
            //
            InvalidatePageSource(_pageIndex);

            //
            //
            _version = _engine.Version;
        }

        private void InvalidatePageSource(int page)
        {
            page = Math.Clamp(page, 1, 255);

            //
            //
            var index  = (page - 1) * PerPageCount;
            var remain = Math.Clamp(_collection.Count - index, 0, PerPageCount);
            
            //
            //
            Discusses.AddMany(_collection.Skip(index).Take(remain), true);

            //
            //
            RaiseUpdated(nameof(PageIndex));
            RaiseUpdated(nameof(PageCount));
        }

        private async void DoAddDiscussCommand()
        {
            var owner = await CharacterPickerViewModel.SingleOf();

            if (!owner.IsFinished)
            {
                return;
            }
            
            var r     = await MasterDetailViewModel.New(TitleSR.New, "添加新的帖子");

            if (!r.IsFinished)
            {
                return;
            }


            var discuss = ForumFactory.CreateDiscuss(r.Value.Name, r.Value.Intro, owner.Value.Id);
            
            //
            //
            _engine.Add(discuss);

            //
            //
            if (Discusses.Count >= PerPageCount)
            {
                _collection.Add(discuss);
                InvalidatePageSource();
                _pageIndex++;
                RaiseUpdated(nameof(PageIndex));
            }
            else
            {
                _collection.Add(discuss);
                Discusses.Add(discuss);
            }
        }

        private void DoNextPageCommand()
        {
            if (_pageIndex >= _pageCount)
            {
                return;
            }

            InvalidatePageSource(++_pageIndex);
        }

        private void DoPreviousPageCommand()
        {
            if (_pageIndex < 1 || _pageCount == 0)
            {
                return;
            }


            InvalidatePageSource(--_pageIndex);
        }

        private void DoOpenDiscussCommand(Discuss item)
        {
            if (item is null)
            {
                return;
            }

            var actualValue = _engine.GetDiscuss(item);
            var context     = new PageContext { Id = item.Id };

            //
            //
            context.Set<Discuss>(ContextBase.Key_Value, actualValue);

            //
            //
            GoTo<ForumEditorViewModel>(context);
        }

        private async void DoRemoveDiscussCommand(Discuss item)
        {
            if (item is null)
            {
                return;
            }

            if (item.Threads.Any(x => !x.Removable) && !await WarningOperation(TitleSR.WarningOperation, "这篇帖子中创建了新的帖子，确定要删除吗？"))
            {
                return;
            }

            if (!await RemoveItem())
            {
                return;
            }

            _engine.Remove(item);

        }

        public int PageIndex
        {
            get => _pageIndex;
            set
            {
                _pageCount = value;
                InvalidatePageSource(value);
                RaiseUpdated();
            }
        }
        
        /// <summary>
        /// 获取或设置 <see cref="Selected"/> 属性。
        /// </summary>
        public Discuss Selected
        {
            get => _selected;
            set => SetValue(ref _selected, value);
        }

        public int        PageCount            => _pageCount;
        public ICommandEX AddDiscussCommand    { get; }
        public ICommandEX OpenDiscussCommand   { get; }
        public ICommandEX PreviousPageCommand  { get; }
        public ICommandEX NextPageCommand      { get; }
        public ICommandEX RemoveDiscussCommand { get; }

        public ObservableCollection<Discuss> Discusses { get; }
    }
}